import 'package:flutter_soundmagus/model/model.dart';
import 'package:flutter_soundmagus/util/ble_helper.dart';
import 'package:json_annotation/json_annotation.dart';

part 'EQModel.g.dart';

@JsonSerializable()
class EQItemModel {
  /// 增益
  double ch;
  double q;
  int freq;

  EQItemModel({this.ch = 0, this.q = 3.6, this.freq = 0});

  EQItemModel copyWith({double? ch, double? q, int? freq}) {
    return EQItemModel(
        ch: ch ?? this.ch, q: q ?? this.q, freq: freq ?? this.freq);
  }

  factory EQItemModel.fromJson(Map<String, dynamic> json) =>
      _$EQItemModelFromJson(json);
  Map<String, dynamic> toJson() => _$EQItemModelToJson(this);
}

@JsonSerializable(explicitToJson: true)
class EQModel with ModelResetable, CmdStringable {
  int pdCount;

  int _selectCH = 0;

  ///通道联调配置
  ChConfig chConfig;

  ///选中的频点
  int pd;

  ///当前选中的通道、0-7单选 8-10联调
  int get selectCH {
    return chConfig.selectCh;
  }

  set selectCH(int v) {}

  EQModel(
      {ChConfig? chConfig,
      this.pdCount = kPdCount,
      this.pd = 0,
      List<List<EQItemModel>>? eqItems})
      : this.chConfig = chConfig ?? ChConfig() {
    if (eqItems == null || eqItems.isEmpty) {
      for (int i = 0; i < 8; i++) {
        List<EQItemModel> eqItems = [];
        for (int j = 0; j < freqs.length; j++) {
          EQItemModel eqItem =
              EQItemModel(ch: 0, q: kQDefault, freq: freqs[j].toInt());
          eqItems.add(eqItem);
        }
        this.items.add(eqItems);
      }
    } else {
      this.items = eqItems;
    }
  }

  ///更新eq
  EQModel updateEqItem({double? ch, double? q, int? freq}) {
    var itemModel = getCurrentItemModel().copyWith(ch: ch, q: q, freq: freq);
    var eqItems =
        items.map((e) => e.map((e) => e.copyWith()).toList()).toList();
    eqItems[selectCH][pd] = itemModel;

    //如果是联调，找同组通道同步数据
    var chObj = chConfig.chs[selectCH];
    if (chObj.isGroup) {
      var relativeCH = chConfig.getRelativeCh();
      eqItems[relativeCH][pd] = EQItemModel.fromJson(itemModel.toJson());
    }

    this.items = eqItems;
    return this;
  }

  EQModel copyWith(
      {ChConfig? chConfig,
      int? pdCount,
      int? pd,
      List<List<EQItemModel>>? eqItems}) {
    return EQModel(
        chConfig: chConfig ?? this.chConfig,
        pdCount: pdCount ?? this.pdCount,
        pd: pd ?? this.pd,
        eqItems: eqItems ?? this.items);
  }

  List<List<EQItemModel>> items = [];
  static const List<int> _freqs8 = [
    50,
    125,
    315,
    750,
    1250,
    3200,
    6000,
    16000,
  ];
  static const List<int> _freqs31 = [
    20,
    25,
    32,
    40,
    50,
    63,
    80,
    100,
    125,
    160,
    200,
    250,
    315,
    400,
    500,
    630,
    800,
    1000,
    1250,
    1600,
    2000,
    2500,
    3150,
    4000,
    5000,
    6300,
    8000,
    10000,
    12500,
    16000,
    20000
  ];
  static List<int> get freqs => kPdCount == 8 ? _freqs8 : _freqs31;

  EQItemModel getCurrentItemModel() {
    return getItemModel(this.selectCH, this.pd);
  }

  ///当前通道所有eq频点列表
  List<EQItemModel> getCurrentItemsModel() {
    return getItemsModel(this.selectCH);
  }

  List<EQItemModel> getItemsModel(int selectCH) {
    return this.items[selectCH];
  }

  EQItemModel getItemModel(int selectCH, int pd) {
    return this.items[selectCH][pd];
  }

  factory EQModel.fromJson(Map<String, dynamic> json) =>
      _$EQModelFromJson(json);
  Map<String, dynamic> toJson() => _$EQModelToJson(this);

  @override
  void reset() {
    for (var e in items) {
      for (var item in e) {
        var j = e.indexOf(item);
        item
          ..ch = 0
          ..q = kQDefault
          ..freq = freqs[j].toInt();
      }
    }
    pd = 0;
    chConfig.selectCh  = 0;
  }

  @override
  String toCmdStr() {
    var str = '';
    for (var idx = 0; idx < items.length; idx++) {
      var obj = items[idx];
      for (var idx2 = 0; idx2 < obj.length; idx2++) {
        var obj2 = obj[idx2];
        ZFEqMsg msg = ZFEqMsg();
        msg.ch.value = idx + 0xc1;
        msg.freq.value = obj2.freq;
        msg.gain.value = ((obj2.ch + 20) * 10).toInt();
        msg.q.value = (obj2.q * 100).toInt();
        msg.pd.value = idx2;

        str += '${msg.toHexString()}\n';
      }
    }
    return str;
  }
}

extension EQModelExt on EQModel {
  ///同步通道所有数据到另外联调的通道
  void syncData({int? ch}) {
    var chi = ch ?? selectCH, relaCh = chConfig.getRelativeCh(ch: chi);
    items[relaCh] = items[chi].map((e) => e.copyWith()).toList();
  }
}
